﻿namespace Resharper.Abstractions.Actions
{
  using System;
  using JetBrains.Annotations;
  using JetBrains.Application.Progress;
  using JetBrains.DocumentModel;
  using JetBrains.ReSharper.Intentions.Util;
  using JetBrains.ReSharper.Psi;
  using JetBrains.ReSharper.Psi.CodeStyle;
  using Resharper.Abstractions.CodeDom.TreeNodes;
  using Resharper.Abstractions.Solutions;

  /// <summary>Defines the <see cref="CodeFormatter"/> class.</summary>
  public class CodeFormatter
  {
    #region Constructors and Destructors

    /// <summary>Initializes a new instance of the <see cref="CodeFormatter"/> class.</summary>
    /// <param name="solution">The solution.</param>
    /// <param name="languageType"></param>
    /// <exception cref="System.ArgumentNullException">solution</exception>
    public CodeFormatter([NotNull] Solution solution, PsiLanguageType languageType)
    {
      if (solution == null)
      {
        throw new ArgumentNullException("solution");
      }

      this.Solution = solution;
      this.LanguageType = languageType;
    }

    #endregion

    #region Properties

    /// <summary>
    /// Gets or sets the solution.
    /// </summary>
    /// <value>The solution.</value>
    [NotNull]
    public Solution Solution { get; set; }

    /// <summary>
    /// Gets or sets the type of the language.
    /// </summary>
    /// <value>The type of the language.</value>
    protected PsiLanguageType LanguageType { get; set; }

    #endregion

    #region Public Methods

    /// <summary>Formats the specified result.</summary>
    /// <param name="treeNode">The result.</param>
    /// <exception cref="System.ArgumentNullException">treeNode</exception>
    public void Format([NotNull] TreeNode treeNode)
    {
      if (treeNode == null)
      {
        throw new ArgumentNullException("treeNode");
      }

      ContextActionUtils.FormatWithDefaultProfile(treeNode.InternalTreeNode);
      // this.Format(treeNode.InternalTreeNode.GetDocumentRange());
    }

    #endregion

    #region Methods

    /// <summary>Formats the specified range.</summary>
    /// <param name="range">The range.</param>
    private void Format(DocumentRange range)
    {
      var languageService = LanguageService.GetInstance(this.LanguageType);
      if (languageService == null)
      {
        return;
      }

      var formatter = languageService.CodeFormatter;

      formatter.Format(
        this.Solution.InternalSolution,
        range,
        CodeStyleSettingsManager.Instance.CodeStyleSettings,
        CodeFormatProfile.DEFAULT,
        true,
        true,
        NullProgressIndicator.Instance);
    }

    #endregion
  }
}